CrackMe v. 1.00
by aLoNg3x
Tutorial by Lucifer48 [Immortal Descendants]
(1 august 1999)
The crackme is written in delphi... with this beautiful icon...
I fill my name and my serial (i put a bpx hmemcpy), it's very classical:
XXXX:00442C9C CALL 004232C0 ;we exit from here
XXXX:00442CA1 MOV EAX,[EBP-08]
XXXX:00442CA4 LEA EDX,[EBP-04]
...
XXXX:00442D07 MOV EAX,[EBP-10] ;name
XXXX:00442D0A POP EDX ;serial
XXXX:00442D0B CALL 00442A3C ;check the serial
XXXX:00442D10 TEST AL,AL
XXXX:00442D12 JZ 00442D23 ;jump = bad serial
This a small source in Borland C++ Builder (v4.0) to show what's happen in the call 00442A3C:
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1KeyUp(TObject *Sender, WORD &Key,
TShiftState Shift)
{
int i, result=0;
AnsiString name;
name=Edit1->Text; /* Edit1: edit box for the name */
if ((name!="")&&(name.Length()>5)&&(name.Length()<11))
{
for(i=1; i<name.Length(); i++)
result += name[i+1]*name[i]*i;
result = result + name.Length() - 666;
Edit2->Text=result;
}
else
Edit2->Text=""; /* Edit2: edit box for the serial */
}
//---------------------------------------------------------------------------
I get my own registration:
Name/ Lucifer48
Serial/ 290812
With that, the "OK" button is enabled, i click on it and nothing ! The "OK" button is disabled
again. I try to see, what's happen when i click on ok and nothing interesting...
The check is elsewhere...
In fact, the true check is done when you click on the "Cancella" button;
it is practically the same code as above:
...
XXXX:00442EE3 MOV EAX,[EBP-04] ;name
XXXX:00442EE6 POP EDX ;edx: value of the serial in hexa
XXXX:00442EE7 CALL 00442AF4 ;check
XXXX:00442EEC TEST AL,AL
XXXX:00442EEE JZ 00442F0C ;jump = bad serial
In the call 00442AF4:
XXXX:00442B3A CALL 00442A20 ;EAX! i mean: fact(eax)
XXXX:00442B3F MOV ESI,EAX ;save the result
...
XXXX:00442B4F MOV EDX,00000001
XXXX:00442B54 MOV ECX,[EBP-04] ;adress of name
XXXX:00442B57 MOVZX ECX,BYTE PTR [EDX+ECX-01] ;read one by one the chars of the name
XXXX:00442B5C IMUL ECX,ESI
XXXX:00442B5F ADD EBX,ECX
XXXX:00442B61 INC EDX
XXXX:00442B62 DEC EAX
XXXX:00442B63 JNZ 00442B54 ;loop (length of name)
XXXX:00442B65 SUB EBX,[EBP-08] ;the serial (in hexa)
XXXX:00442B68 CMP EBX,00007A69
XXXX:00442B6E JNZ 00442B74 ;must be equal...
This is a small part of the keygen:
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1KeyUp(TObject *Sender, WORD &Key,
TShiftState Shift)
{
int i, f, result=0;
AnsiString name;
name=Edit1->Text; /* Edit1: edit box for the name */
if ((name!="")&&(name.Length()>5)&&(name.Length()<11))
{
f=fact((name[5]%7)+2); /* fact(n) = 1*2*...*(n-1)*n */
for(i=1; i<=name.Length(); i++)
result = result + name[i]*f;
result -= 0x7a69;
Edit2->Text=result;
}
else
Edit2->Text=""; /* Edit2: edit box for the serial */
}
//---------------------------------------------------------------------------
I press on the "Cancella" button; it is erased. We passed a step ! Still one button.
I get my own registration:
Name/ Lucifer48
Serial/ 560503
Note: There is no problem to enter negative numbers.
(example: Name/ L48 [ID] Serial/ -30255 )
Remark: I'd like to say few words about the way delphi has compiled the factorial function
(in the call 00442A20):
XXXX:00442A20 PUSH EBX ;13 lines of code only !!
XXXX:00442A21 MOV EBX,EAX ;and nothing superfluous !!
XXXX:00442A23 TEST EBX,EBX
XXXX:00442A25 JNZ 00442A2E
XXXX:00442A27 MOV EAX,000000001 ;
XXXX:00442A2C POP EBX ;end of recursion
XXXX:00442A2D RET :
XXXX:00442A2E MOV EAX,EBX
XXXX:00442A30 DEC EAX
XXXX:00442A31 CALL 00442A20
XXXX:00442A36 IMUL EBX ;
XXXX:00442A38 POP EBX ;(result of the multiplication EDX:EAX, with EDX dword..
XXXX:00442A39 RET ; ..of high weigth)
We find this algo in high level languages:
Let's continue the crackme, we have to kill the "OK" button (with the same way of above):
XXXX:00442DBD MOV EAX,[EBP-04] ;name
XXXX:00442DC0 POP EDX ;serial (in hexa)
XXXX:00442DC1 CALL 004232C0 ;check the serial
XXXX:00442DC6 TEST AL,AL
XXXX:00442DC8 JZ 00442DD7 ;jump = bad serial
In the call 004232C0:
XXXX:00442C09 MOVZX EAX,BYTE PTR [ESI+EAX-01]
XXXX:00442C0E IMUL EAX ;EAX^2
XXXX:00442C10 MOVSX EAX,AX ;if AX>7FFF then EAX=(EAX or $FFFF0000)
XXXX:00442C13 IMUL ESI
XXXX:00442C15 MOV ECX,00000019 ;1A would be better for getting a "Z" char...
XXXX:00442C1A CDQ
XXXX:00442C1B IDIV ECX
XXXX:00442C1D ADD EDX,41
XXXX:00442C20 POP EAX
XXXX:00442C21 MOV [EAX],DL ;adress of the serial
XXXX:00442C23 DEC ESI ;we start by the last char
XXXX:00442C24 TEST ESI,ESI
XXXX:00442C26 JNZ 00442BF9 ;loop (length of serial)
XXXX:00442C28 MOV EAX,[EBP-0C] ;serial "encoded"
XXXX:00442C2B MOV EDX,[EBP-04] ;name
XXXX:00442C2E CALL 00403B44 ;comparison of the two strings
XXXX:00442C33 JNZ 00442C4C ;jump = bad serial
If you look at the loop, you see that the name must only have capitals letter (from 41h to 59h,
without the Z char...) And of course, the serial and the name have the same length.
Let's find (or rather let's try to find...) a serial for my name:
L U C I F E R
4C 55 43 49 46 45 52
I recall that; we only can enter numbers in the serial. So:
(X7^2 * 7) mod 19 + 41 = 52 <=> (X7^2 * 7) mod 19 = 11
(X6^2 * 6) mod 19 + 41 = 45 <=> (X6^2 * 6) mod 19 = 04
(X5^2 * 5) mod 19 + 41 = 46 <=> (X5^2 * 5) mod 19 = 05
(X4^2 * 4) mod 19 + 41 = 49 <=> (X4^2 * 4) mod 19 = 08
(X3^2 * 3) mod 19 + 41 = 43 <=> (X3^2 * 3) mod 19 = 02
(X2^2 * 2) mod 19 + 41 = 55 <=> (X2^2 * 2) mod 19 = 14
(X1^2 * 1) mod 19 + 41 = 4C <=> (X1^2 * 1) mod 19 = 0B
I've done a small prog on my calculator which try the 10 (unique) possibilities (from 30h to 39h):
For X7: i get: { 3h, 7h, 0h, 7h, 3h, Dh, Ch, 0h, 2h, 12h }
For X6: i get: { 18h, 6h, 0h, 6h, 18h, 4h, 15h, 0h, 10h, 13h }
For X5: i get: { 14h, 5h, 0h, 5h, 14h, 14h, 5h, 0h, 5h, 14h }
For X4: i get: { 10h, 4h, 0h, 4h, 10h, Bh, Eh, 0h, 13h, 15h }
For X3: i get: { Ch, 3h, 0h, 3h, Ch, 2h, 17h, 0h, 8h, 16h }
For X2: i get: { 8h, 2h, 0h, 2h, 8h, 12h, 7h, 0h, 16h, 17h }
For X1: i get: { 4h, 1h, 0h, 1h, 4h, 9h, 10h, 0h, Bh, 18h }
We see that X7, X4 and X2 are impossible to solve ! A big error from the author...
Acceptable chars (in the right order):
For X7: "D","H","A","H","D","N","M","A","C","S"
For X6: "Y","G","A","G","Y","E","V","A","Q","T"
For X5: "U","F","A","F","U","U","F","A","F","U"
For X4: "Q","E","A","E","Q","L","O","A","T","V"
For X3: "M","D","A","D","M","C","X","A","I","W"
For X2: "I","C","A","C","I","S","H","A","W","X"
For X1: "E","B","A","B","E","J","Q","A","L","Y"
With this, i can't build my name... I can do
Name/ LICQFED
Serial/ 8050150 (or 8050350 or...)
Or more simply:
Name/ AAAAAA
Serial/ 222222
Remark: To be complete; we can put a "-" char as first char of the serial. So 2Dh become "A".
The "OK" button is erased...
Greetings: All ID members (Volatility, Torn@do, ...), Eternal Bliss, ACiD BuRN, LaZaRuS,
Duelist, people on #cracking4newbies, ...
(c) Lucifer48. All rights reversed